package com.gjs.sso.config.security.sms;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * autor:liman
 * createtime:2021/7/11
 * comment:短信验证码登录的认证逻辑
 */
@Data
public class SmsVerifyCodeProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    public SmsVerifyCodeProvider(UserDetailsService userDetailsService){
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SmsVerifyCodeAuthenticationToken smsVerifyCodeAuthenticationToken = (SmsVerifyCodeAuthenticationToken) authentication;
        String mobile = (String) smsVerifyCodeAuthenticationToken.getPrincipal();
        UserDetails userInfo = userDetailsService.loadUserByUsername(mobile);//根据手机号读取用户信息
        if (null == userInfo) {
            throw new UsernameNotFoundException("用户不存在");
        }

        // 登录成功，则需要重新构造UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken authenticationResult = new UsernamePasswordAuthenticationToken(userInfo.getUsername(),userInfo.getPassword(),userInfo.getAuthorities());
        // 未认证的token中detail信息也要复制到认证之后的请求信息
        authenticationResult.setDetails(smsVerifyCodeAuthenticationToken.getDetails());

        return authenticationResult;
    }

    /**
     * 当前provider支持的认证类型是哪一种
     */
    @Override
    public boolean supports(Class<?> authentication) {
        //判断传进来的是否是SmsVerifyCodeAuthenticationToken
        return SmsVerifyCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

